Technical Note TN2064
Ensuring Backwards Binary Compatibility - Weak Linking and Availability Macros on Mac OS X

目次

このテクニカルノートでは、最新版の Mac OS X 上で構築された Mach-O アプリケーションを旧版の Mac OS X で効果的に動作させる方法と、アプリケーションが旧版の Mac OS X には存在しない API を使用している場合の対処について説明します。

この問題を扱うためにアップルが提供している技術に、ウィークリンクと可用性マクロがあります。

このテクニカルノートでは、これらの技術の仕組み、利点と制限、および Mac OS X での使い方を説明します。 Mach-O アプリケーションを書いていて、現在の OS の API を使っているために、旧版の Mac OS X で正常に実行できない心配がある場合は、このテクニカルノートをお読みください。

[2003 年 2 月 18 日]






概要

本稿では Mac OS X のウィークリンクと可用性マクロの機能の詳細を説明します(Mac OS X 10.0.x については触れませんが、本稿の目的を考えると 10.0.x での動作も 10.1.x とほとんど同じです)。 解説に入る前に、Mac OS X 10.2.x と December 2002 Mac OS X Developer Tools の現状を大まかにまとめておきます。

  • 複数のバージョンの Mac OS X で動作するように設計されたアプリケーションがあり、それがより新しいバージョンの Mac OS X でしか利用できないシンボルを使っている場合は、アプリケーションはウィークリンクを使う必要があります。そうしないと、アプリケーションが使うすべてのシンボルをエクスポートできない旧バージョンの Mac OS X では、そのアプリケーションを起動できません。
  • ウィークリンクは Mac OS X v10.2 で初めてサポートされました。 したがって、アプリケーションを 10.1.x と 10.2 の両方で動作させるためには使えません。 アプリケーションを 10.1.x と 10.2 の両方で動作させる方法は別にあります。
  • 可用性マクロはアップルが提供する API で自動的にウィークリンクを利用できるようにするために導入されました。さらに、開発者によって選択された OS のバージョンで利用できる API のみをアプリケーションが使うようにできます。
  • ウィークリンクと可用性マクロはどちらも新しく導入された技術で、まだ開発途中です。 しかし、December 2002 Mac OS X Developer Tools で大幅な改良が加えられました。 このためウィークリンクと可用性マクロを使うのであれば、この December 2002 版のツールセットを使用することを強くお勧めします。
  • ウィークリンクのサポートと可用性マクロにはさらなる改良が予定されています。定期的にここをチェックして、ツールと OS のサポートの最新情報を確認してください。

問題はなにか

Mach-O アプリケーションを書く際に、最新版の Mac OS X で追加され、それよりも前のバージョンには存在しない新しい API を使いたくなることがよくあります。 しかし、そうして書いたアプリケーションを旧版のシステムで実行しようとすると、プログラムは(a)起動できない、(b)実行中にクラッシュする、(c)正しく実行するが旧版の Mac OS X では事前バインドできない、のいずれかになります。以下に、それぞれのケースを見ていきます。

(a)アプリケーションが起動しない

リンカ(「ld」と呼ばれるプログラム)がアプリケーションをそれが使用するフレームワーク(Carbon や Cocoa など)やライブラリにリンクすると、アプリケーションバイナリの中にエントリが作られます。 これらのエントリは、アプリケーションがリンクするフレームワークと、それらのフレームワークの中からアプリケーションが利用するシンボル(関数、グローバル変数)の両方から参照されます。 これらのエントリを見るには、Terminal を起動してバイナリに対して otool -l を実行します。 このコマンドは、バイナリのロードコマンドを出力します。ロードコマンドの多くは、LC_LOAD_DYLIB のあとにアプリケーションがリンクされている共有ライブラリまたはフレームワークのパスが続く形式を取ります。 リスト 1 に、otool -l の出力の一部を示します。

リスト 1. /usr/bin/perl からのロードコマンドを示すコード - perl は /usr/lib/libSystem.B.dylib に対してリンクされます

username% otool -l /usr/bin/perl  
.
.
.
Load command 6
cmd LC_LOAD_DYLIB
cmdsize 52
name /usr/lib/libSystem.B.dylib (offset 24)
time stamp 1028942768 Fri Aug  9 18:26:08 2002
current version 60.0.0
compatibility version 1.0.0
.
.
.                         

otool の詳細については、マニュアルページを参照してください。 アプリケーションの起動時にバイナリによってリンクされたフレームワークまたは共有ライブラリが存在しない場合(つまり、おそらく AddressBook.framework のようにフレームワークが 10.2 にはあって 10.1 にはない場合)、dyld(ダイナミックローダ)は、アプリケーションの起動時に実行に失敗します。

リスト 2. アプリケーションを実行しようとしたときに、それがリンクしているフレームワークの 1 つがない場合に何が起こるか - dyld がエラー(/usr/include/sys/errno.h から ENOENT = 2)を生成します

username% ./test 
                          
dyld:./test can't open library:
./MyFramework.framework/Versions/A/MyFramework  (No such file or
directory, errno = 2)                        

これよりいくらか一般的で、もう少し複雑なケースとして、フレームワーク自体は実行時に存在しているのに、アプリケーションが使っているシンボルが見つからないことがあります。 たとえば、10.2 で新しく導入された Carbon.framework のルーチンを使っていて、それらが 10.1.x の実行時には存在しない場合などです。 nm -mg を実行することによって、他のフレームワークまたはライブラリからインポートしようとしているシンボルのリストを取得できます(詳細は nm のマニュアルページを参照)。これにより、シンボルがどのように参照されているかと、それらがどのライブラリまたはフレームワークに由来するものであるかが分かります。

リスト 3 ./usr/bin/perl によってインポートされたシンボルの一部を示すコード

username% nm -mg /usr/bin/perl

900154a0 (prebound undefined [lazy bound]) external
_NSAddressOfSymbol (from libSystem)
90021440 (prebound undefined [lazy bound]) external
_NSCreateObjectFileImageFromFile (from libSystem)
.
.
.
a0ea736c (prebound undefined) [referenced dynamically] external
_PL_do_undump (from libperl)
a0ea8dcc (prebound undefined) [referenced dynamically] external
_PL_markstack_max (from libperl)
a0ea8dc8 (prebound undefined) [referenced dynamically] external
_PL_markstack_ptr (from libperl)                  

アプリケーションが使っているシンボルが起動時に存在せず、そのシンボルが遅延バインド(後述)されていない場合は、シンボルがリンクされているフレームワークまたはライブラリが存在していても、アプリケーションは起動に失敗します。 これが起きると、dyld は、見つけられなかったシンボルのリストを表示します。リスト 4 にその例を示します。

リスト 4 .アプリケーションを実行しようとしたときに、それがリンクしているフレームワークからインポートするシンボルの 1 つがない場合、何が起きるか

username% ./test

dyld:./test Undefined symbols:
./test undefined reference to _SayHello expected to be defined in
MyFramework                      

(b)プログラム実行中にアプリケーションがクラッシュする

メモリアドレスを起動後すぐに解決する必要のない、変数以外のシンボル(たとえば関数)は、リンカによって「遅延バインド」のマークが付けらられます(リスト 3 に、遅延バインドシンボルを示す nm の出力例があります)。こうしたシンボルは、dyld によってそのソースフレームワークに遅延バインドされます。dyld はそれらのシンボルが実際に必要になるまでバインドしません。 必要が生じなければ、シンボルはバインドされず、アプリケーションはそれらのシンボルがフレームワークまたはライブラリに含まれていないバージョンの OS 上でもまったく問題なく動作できます。 シンボルが参照されると、その関数の使用が引き金となり dyld に対して解決要請が出されます。これを受けて dyld は、問題となっている実際の関数にジャンプする前にシンボルを解決しようとします。 通常、ほとんどの関数は遅延バインドされます。ただし、そのアドレスがポインタに格納されていると、遅延バインドできない場合もあります。 この場合、dyld は、関数の実行前にシンボルのアドレスを解決する機会があることを保証できず、関数は非遅延バインドになります。 リスト 5 に、遅延バインドされるシンボルと非遅延バインドされるシンボルの両方を生成するコードの例を示します。

リスト 5 . InitCursor() は、関数のアドレスがポインタにコピーされており、dyld がそれを自動的に解決する能力を超えてしまうため、遅延バインドされません。 一方、ObscureCursor() は遅延バインドされます。dyld は最初に明示的に起動されたときに、そのシンボルを解決できることが分かるからです。

void (*foobar)(void);

foobar=InitCursor; // InitCursor は非遅延バインドを強制される
foobar();

ObscureCursor(); // ObscureCursor は遅延バインドされる              

遅延バインドを使うことによる問題は、開発者がコードをどのように書くかによって、アプリケーションで対象となるバージョンの OS に存在しないシンボルを使われる可能性があることです。 あるコードパスが後に続く場合にはアプリケーションの起動と実行がうまくいき、別のコードパスが後に続く場合にはクラッシュすることがあります(dyld は指定されたコードパス内で到達できるシンボルを解決しようとします)。 可用性マクロ(後述)は、アプリケーション内の新しいシンボルの使用の検出を支援できますが、それもすべてのシンボルに確実に適切な条件付けが行われているかに依存します。

(c)アプリケーションは実行できても、旧バージョンの OS では事前バインドできない

存在しないシンボルをバインドするアプリケーションのもう 1 つの問題は、遅延バインドされたものも含めてすべてのノンウィークシンボル(後述)の事前バインドが破壊される(そして修復できない)ことです。 アプリケーションで事前バインドが破壊されるということは、通常は、起動に時間がかかることを意味します。 つまり遅延バインドは、実行時に存在しないかもしれない API の使用を条件付けするための十分な解決策ではないということです。たとえ、旧版の OS 上でアプリケーションが実行される場合に新しい API が絶対に呼び出されないように注意していたとしても不十分です。

先頭に戻る

解決策:ウィークリンク

これらの問題を解決するためにアップルが開発した解決策は「ウィークリンク」と呼ばれるものです。 これは、CFM (Traditional Mac OS の Code Fragment Manager)にあった同様の名前の機能に似ています。ウィークリンクは OS がサポートする機能として Mac OS X version 10.2 で導入され、ウィークリンクをサポートする初めての開発ツールセットは July 2002 Developer Tools で、Mac OS X version 10.2 の一部として出荷されています。以下でその仕組みを解説します。

ウィークリンクを使ってシンボルをリンクすると、実行時にそのシンボルが存在しなくてもバイナリの実行を継続することができます。 もちろん、プログラムは実際には存在しないシンボルを使おうとすることはできず、そうした場合にはクラッシュします。 その代わり、コードでシンボルのアドレスが NULL かどうかをチェックする必要があります。 NULL であればシンボルは存在しませんが、アドレスが実アドレスならばシンボルは存在し、使用できます。

シンボルは、そのプロトタイプを明示的にウィーク(weak)と指定しない限りはストロングリンクされます。通常これはルーチンのプロトタイプを含むヘッダで、weak_import 属性(Mac OS X 上の gcc 3.1 でサポートされています。gcc 2.95 ではサポートされていません)をプロトタイプに追加することによって行われます。属性の詳細については、gcc のWeb サイトにあるドキュメント を参照してください。

リスト 6. SayHello 関数はプロトタイプに weak_import 属性を使ったおかげでウィークリンクされます

extern int SayHello() __attribute__((weak_import));
             

weak_import 属性を使って、シンボルをウィークリンクするようにリンカに指示できます。 しかし、Mac OS X 10.2 よりも前のバージョンでは、ld や dyld の機能としてウィークリンクは存在しないため、コンパイルの前に環境変数を設定して、v10.2 から導入された機能が使われる可能性があることをリンカに知らせることによって、明示的にこれを使用できるようにする必要があります。 リスト 7 に、Terminal からこの環境変数を設定する方法を示します。

リスト 7. ウィークリンクも含めた Mac OS X 10.2 の機能を自由に使えることをリンカに知らせる必要があります

setenv MACOSX_DEPLOYMENT_TARGET 10.2
             

環境変数が少なくとも 10.2 に設定されていない場合(設定しないと 10.1 の値であると見なされます)、weak_import 属性を使おうとした場合に、次のような警告が表示されます。

リスト 8. MACOSX_DEPLOYMENT_TARGET に十分に大きなバージョンが設定されていないと、ウィークリンクは警告を出します

test.c:4:warning:weak_import attribute ignored when
MACOSX_DEPLOYMENT_TARGET environment variable is set to 10.1
             

MACOSX_DEPLOYMENT_TARGET 関数は、 Project Builder のターゲットのビルド設定でも設定できるようになり、その IDE の中からウィークリンクを使うことができます。

 

the dogcow

図 1. カスタムビルド設定を追加して MACOSX_DEPLOYMENT_TARGET 環境変数を設定する

環境変数が設定され、関数プロトタイプに正しく weak_import 属性が設定されていれば、コンパイルを行うと ld は最終的なアプリケーション内でそのシンボルをウィークリンクとしてマークします。 本稿の前半で nm ツールを使って、アプリケーションがインポートするシンボルと、それらのシンボルがどのように参照されるかを調べました。nm -mg |grep frameworkname を使えば、特定のフレームワークから参照するすべてのシンボルのリストを生成し、それらがバイナリの中でウィークであるかどうかを知ることができます。

リスト 9. _SayHello シンボルの記述(MyFramework からインポート)をウィークとしてマークしています

username% nm -mg test | grep MyFramework
(undefined) weak external _SayHello (from MyFramework)             

バイナリがウィークリンクされたシンボルで構築されると、それらのシンボルの有無は実行時にチェックされます。たとえば、次のようになります。

リスト 10. SayHello 関数が実行時に存在するかどうかのテスト示すテストプログラム

#include <stdlib.h>
#include <stdio.h>

extern int SayHello() __attribute__((weak_import));

int main()
{
	int result;
	
	if (SayHello!=NULL)
	{
		printf("SayHello is present!¥n");
		result=SayHello();
	}
	else
		printf("SayHello is not present!¥n");
}             

ウィークリンクに対するこのアプローチ全体が前提としているのは、ウィークリンクされるのは個々のシンボルであって、フレームワークまたはライブラリ全体ではないと指摘されるかもしれません。実際その通りです。理想的には必要以上のシンボルをウィークリンクしないようにして、dyld が不足のシンボルについて可能な限り早く完全にフラグを立てる能力を維持するべきです。 しかし、場合によっては、フレームワークまたは共有ライブラリ全体をウィークリンクして、それがエクスポートする個別のシンボルだけではなく、フレームワーク全体が実行時にないことを許容するほうが現実に望ましいことがあります。 これはリンカによって、次のように行われます。 指定されたフレームワークからアプリケーションがインポートするシンボルがすべてウィークリンクされていると、フレームワークまたは共有ライブラリをロードするアプリケーションのロードコマンドの中で、そのフレームワーク全体がウィークであると自動的にマークされます。 バイナリに対して otool -l を実行すると(リスト 1 で行ったように)、フレームワーク全体がウィークリンクされているかどうかが示されます。

リスト 11. フレームワークを「ウィークロード」するロードコマンドを示すコード - LC_LOAD_WEAK_DYLIB に注目

username% otool -l test
.
.
.
Load command 5
cmd LC_LOAD_WEAK_DYLIB
cmdsize 72
name ./MyFramework.framework/Versions/A/MyFramework
(offset 24)
time stamp 3247416188 Wed Oct 21 05:34:52 1936
current version 0.0.0
compatibility version 0.0.0
.
.
.                         

多数のウィークリンクを使うことで生じる問題の 1 つは、特定のバージョンの OS ではどのルーチンを使えるかを、どうすれば分かるかということです。 アップルが提供するシステムフレームワークのヘッダが、対象となる OS のバージョンに合わせてそれ自身を自動的に設定し、ルーチンに適切にウィークのマークを付けられると良いと思ったことはありませんか?ここで可用性マクロが登場します。

先頭に戻る

  

解決策:可用性マクロ

Mac OS X v10.2 で、July 2002 Developer Tools の一部として可用性マクロ(Availability Macros)と呼ばれるマクロのセットが導入されました。 これらは、システムの「/usr/include/AvailabilityMacros.h」にあるヘッダに含まれています。 「AvailabilityMacros.h」は、使用されている API がどのバージョンの OS で導入されたものかを判断し、コンパイラにどのルーチンをウィークリンクするべきかを指示します。今後、アップルのフレームワークのより多くの部分で可用性マクロが採用される予定です(Carbon と Cocoa の両フレームワークでは、すでにある程度そうなっています)。

「可用性マクロ」は、その最も基本的なレベルでは、API がどのように定義されるかを決めるために設定できる、2 つのコンパイル時変数(またはマクロ)を提供しています。以下に、その働きを示します。

MAC_OS_X_VERSION_MIN_REQUIRED

このマクロは特定のバージョンの OS に設定でき(OS のバージョンを事前定義するいくつかのマクロがヘッダ内で提供されています)、これを使ってアプリケーションの実行に必要な OS の最小バージョンを指定できます。可用性マクロを使うすべての API は、それらがリリースされたバージョンの OS に条件付けされており、必要とされる最小 OS バージョンまでに導入されているすべての API は、ストロングリンクする必要があります。 「AvailabilityMacros.h」には、MAC_OS_X_VERSION_MIN_REQUIRED が未定義の場合、デフォルトで 10.0 に設定されることが示されています。 これは、MACOSX_DEPLOYMENT_TARGET が設定されていなければ正しい設定ですが、ヘッダからでは分からないのは、コンパイラドライバが MACOSX_DEPLOYMENT_TARGET 環境変数をチェックし、MACOSX_DEPLOYMENT_TARGET が設定されていたら、MAC_OS_X_VERSION_MIN_REQUIRED の値を MACOSX_DEPLOYMENT_TARGET と同じ値に設定するかどうかです。

MAC_OS_X_VERSION_MAX_ALLOWED

このマクロでは、アプリケーションが使用できる API の最大 OS バージョンを指定できます。 ある API が最初に導入された OS のバージョンが、このマクロで指定された最大バージョンよりも大きい場合、その API はアプリケーションからは見えません。 必要な最小 OS バージョンよりも後で、最大 OS バージョンまでに導入された API は、自動的にウィークリンクされます。 このマクロに値が指定されていない場合には、可用性マクロが認識する最大のメジャー OS バージョンに設定されます(本稿執筆時は 10.2)。

ある使用法

これらのマクロの 1 つの一般的な使い方は、一時的に MAC_OS_X_VERSION_MAX_ALLOWEDMAC_OS_X_VERSION_MIN_REQUIRED と等しい値に設定してアプリケーションを再構築し、使用されているどの API が必須の最小 OS バージョンに含まれていないかを判定します(コンパイルを行うと、今突然に利用できなくなったルーチンのそれぞれについてエラーが生成されます)。たとえば、MAC_OS_X_VERSION_MIN_REQUIRED を 10.1 に設定して(コンパイラに対しては 1010 と表現)、MAC_OS_X_VERSION_MAX_ALLOWED も 10.1 に設定した場合、たとえば 10.2 で導入された API のどちらが使われるかを見ます。 この使用法は、December 2002 Developer Tools の時点で、Cocoa と Carbon のどちらのフレームワークでも機能します。

先頭に戻る

代替解決策:バンドルと CFBundle

10.1.x で実行する必要のあるアプリケーションで、10.2 で導入された API を使う必要がある場合、ウィークリンクは選択肢になりません。ではどうすれば、この特定の OS バージョンの移行を行えるのでしょうか。相互にいくらか似た 2 つの主要な解決策があります。いずれも本質的には、アプリケーションで「手作業でのウィークリンク」を行うものです。

CFBundle

CFBundleCFBundleGetFunctionPointerForName のような、関数ポインタやシンボルをバンドルから手動でロードするのに使える API を含みます(フレームワークは有効なバンドルです)。CFBundle の使用は、新たに導入されたシンボルの条件ローディングと、それらが存在する場合の呼び出しを行う良い方法です。CallMachOFramework コードサンプルには、このルーチンを CFM アプリケーションの Mach-O シンボルをロードするコンテキストで使う例が示されています。CFBundle ドキュメントには、このテクニックのもう 1 つの良い例が示されています。

バンドル

上記のアプローチのように、CFBundleGetFunctionPointerForName を使うのは必要なシンボルの数が少ないときにはうまくいきます。 しかし、システムフレームワークから個々のシンボルを手動で直接ロードするのは、新たに導入されたシンボルが多数必要な場合は(たとえば AddressBook API のような新しい機能領域を採用している場合は)、かなりの手間になります。 この状況での最良のアプローチは、機能領域を、10.2 のシステムフレームワークに直接リンクされ、主要エントリポイントの数が少ないそれぞれのバンドルに分離してから、アプリケーションが 10.2 以降で実行されている場合には、そのバンドルだけを(CFBundle を使って)ロードすることです。 バンドル内部では、10.2 固有の API を自由に直接使用できます。バンドルをロードしているアプリケーションはすでに新しい API が存在していると判断しているからです。

December 2002 Developer Tools/Headers での要検討項目と問題点

ウィークリンクと可用性マクロは、Mac OS X 10.2 および December 2002 Developer Tools では初めて実装された機能です。 December 2002 Developer Tools では、July 2002 Developer Tools に全体的に大幅な改善が施され、今後もさらに改善されていく予定です。現時点での要検討項目、問題点、および解決策としては、次のようなものがあります。

  • Objective-C の長所の 1 つは、そのランタイムが十分に動的で、C や C++ などの他の言語でウィークリンクが設計して解決しようとしたストロングリンクやバイナリ互換性の問題がないことです。つまり、アプリケーションがそれらの存在を実行時に確認し、適切にそれらの使用を避ける限りにおいては先に進み、新たに導入された Objective C のメソッドとクラスおよびアプリケーションを、新しいシンボルを持たない旧バージョンの Mac OS X 上でも実行できるようにします。 ただし、Cocoa は、現時点ではストレートな C 関数については、たとえそれが MAC_OS_X_VERSION_MIN_REQUIRED よりも後で、 MAC_OS_X_VERSOIN_MAX_ALLOWED よりも前に導入されたものであっても、自動的にはウィークリンクしません (r. 3151928)。
  • ウィークリンクは Mac OS X version 10.2 以降の dyld でのみサポートされています。 したがって、10.1.x 上で実行する必要のあるアプリケーションでは使えません。ウィークリンクされたシンボルは、10.1.x 上ではストロングリンクされたシンボルだと見なされるので、フレームワークまたは共用ライブラリにウィークリンクされたアプリケーションは、10.1.x 上で起動しようとするとクラッシュします。
  • December 2002 Mac OS X Developer Tools には既知のバグがあります。フレームワークまたは共有ライブラリであるライブラリ A とライブラリ B にリンクするとき、ライブラリ A に含まれるシンボルは使わず、ライブラリ B に含まれるシンボルを使い、ライブラリ B はライブラリ A に含まれるシンボルを使うものとすると、リンカはライブラリ A にウィークリンクしようとします。しかし、 MACOSX_DEPLOYMENT_TARGET が 10.2 以上に設定されていると、以前の OS バージョンはウィークリンクをサポートしないため、これは失敗することになり、警告が出されます。警告は次の形式を取ります:“ld:warning dynamic shared library: /usr/lib/libSystem.dylib not made weak library in output with MACOSX_DEPLOYMENT_TARGET environment variable set to: 10.1". このバグは Mac OS X Developer Tools の次のメジャーリリースで修正される予定です (r. 3094497)。それまでは、この警告を出さないようにするには、MACOSX_DEPLOYMENT_TARGET を 10.2 に設定するか、または使用するシンボルのあるライブラリの擬似呼び出しを作成して、リンカにそれをストロングリンクさせます。

プリコンパイル済みヘッダの処理のために新しい Persistent Front End(PFE)機構(December 2002 Developer Tools の新規プロジェクトの標準設定)ではなくて、cpp-precomp(July 2002 Developer Tools 以前の標準設定)をプリコンパイル済みヘッダを使う場合には、の処理に使っている場合には、MACOSX_DEPLOYMENT_TARGETMAC_OS_X_VERSION_MIN_REQUIRED,、および MAC_OS_X_VERSION_MAX_ALLOWED をプロジェクトベースで設定する明らかな方法はありません。すでにこれらの値を定義しているフレームワークのプリコンパイル済みヘッダのシステム全体のコピーは1つしかないからです。プロジェクト内でこれらの設定を再定義するとプリコンパイル済みヘッダが破壊され、コンパイル時間が大幅に延びます(また、大量の警告が生成されます)。これを修正する方法は 2 通りあります。

  1. プロジェクトごとに、プリコンパイル済みヘッダに新しい Persistent Front End (PFE) メカニズムを使用します。 プロジェクトの「ターゲット」タブの「ビルド設定」を使ってこれを行うことができます。
  2. 適切な設定が定義されたシステムのプリコンパイル済みヘッダを(必要に応じて)、それらの設定を必要とするプロジェクトの構築を開始する前に再構築します。cpp-precomp のプリコンパイル済みヘッダは、リスト 12 に示すようにコマンドラインから fixPrecomps コマンドを使って再構築できます。

リスト 12. ウィークリンクと可用性マクロフラグの設定および cpp-precomp のプリコンパイル済ヘッダの再ビルドを示すコード

username% setenv MACOSX_DEPLOYMENT_TARGET 10.1
username% sudo fixPrecomps -force -precompFlags
-DMAC_OS_X_VERSION_MIN_REQUIRED=1010
-DMAC_OS_X_VERSION_MAX_ALLOWED=1010

reading /System/Library/SystemResources/PrecompLists/phase1.precompList
reading /System/Library/SystemResources/PrecompLists/phase2.precompList
-force rebuild /usr/include/libc.p.
/usr/bin/gcc3 -precomp -x objective-c /usr/include/libc.h -o
/usr/include/libc-gcc3.p -DMAC_OS_X_VERSION_MIN_REQUIRED=1010
-DMAC_OS_X_VERSION_MAX_ALLOWED=1010
.
.
.                         

先頭に戻る

 

変更履歴

2003 年 1 月 21 日

December 2002 Mac OS X Developer Tools の時点の現状を反映して、このテクニカルノートを更新しました。


先頭に戻る

 

参考文献

Mac OS X v10.2 の lddyldnm、および otool のマニュアルページ

Using the GNU Compiler Collection (GCC)』 GNU の Attribute Syntax に関するドキュメント。Copyright 2002 by the Free Software Foundation, retrieved 11/19/2002

DTS のサンプルコード CallMachOFramework

Apple Computer, Inc., CFBundle Documentation, retrieved 11/19/2002

先頭に戻る

ダウンロード

Acrobat gif

このテクニカルノートの PDF 版(208 K)

ダウンロード


先頭に戻る